package cn.aimer.hrm.service.impl;

import cn.aimer.hrm.client.LoginUserClient;
import cn.aimer.hrm.client.ThirdPartyServiceClient;
import cn.aimer.hrm.domain.LoginUser;
import cn.aimer.hrm.domain.VipBase;
import cn.aimer.hrm.domain.VipUser;
import cn.aimer.hrm.dto.RegisterDto;
import cn.aimer.hrm.exception.ValidUtil;
import cn.aimer.hrm.mapper.VipBaseMapper;
import cn.aimer.hrm.mapper.VipUserMapper;
import cn.aimer.hrm.service.IVipBaseService;
import cn.aimer.hrm.util.AjaxResult;
import cn.aimer.hrm.util.BitStatesUtils;
import cn.aimer.hrm.util.UserConstants;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.enums.IdType;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author aimer
 * @since 2022-01-12
 */
@Service
public class VipBaseServiceImpl extends ServiceImpl<VipBaseMapper, VipBase> implements IVipBaseService {

    @Autowired
    private ThirdPartyServiceClient thirdPartyServiceClient;
    @Autowired
    private LoginUserClient loginUserClient;
    @Autowired
    private VipBaseMapper vipBaseMapper;

    @Autowired
    private VipUserMapper vipUserMapper;
    @Override
    //@GlobalTransactional(rollbackFor = Exception.class)
    @GlobalTransactional
    public AjaxResult register(RegisterDto registerDto) {
        //1校验 null+短信验证码+用户检验
        Map<String,String> params = new HashMap<>();
        params.put("key",UserConstants.REGISTER_CODE_PREFIX+registerDto.getMobile());
        params.put("code",registerDto.getSmsCode());
        AjaxResult result = thirdPartyServiceClient.verifySmsCode(params);
        ValidUtil.assertTrue(result.isSuccess(),result.getMessage());
        //2 远程调用hrm-auth保存loginUser并获取到loginId
        LoginUser loginUser = new LoginUser();
        loginUser.setUsername(registerDto.getMobile());
        loginUser.setPhone(registerDto.getMobile());
        loginUser.setUsername(registerDto.getMobile());
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String enPass = bCryptPasswordEncoder.encode(registerDto.getPassword());
        loginUser.setPassword(enPass);
        loginUser.setType(1);
        AjaxResult ajaxResult = loginUserClient.addOrUpdate(loginUser);
        ValidUtil.assertTrue(ajaxResult.isSuccess(),ajaxResult.getMessage());
        Long loginId = Long.valueOf(ajaxResult.getResultObj().toString()) ;
        //3 保存vipBase，vipuser
        VipBase vipBase = new VipBase();
        vipBase.setPassword(enPass);
        vipBase.setUsername(registerDto.getMobile());
        vipBase.setPhone(registerDto.getMobile());
        vipBase.setNickName(registerDto.getMobile());
        // 知识点：在系统中状态表示法
        //1 互斥状态 启用、禁用 上线、下线、待审核、审核失败
        //1.1 方案1：用Boolean-只支持两个状态
        //1.2 方案2（采纳）： int，一个数字表示一个状态
        //2 并行状态  账号状态：一个时刻同时存在多个状态 已经注册并且已经手机实名认证并且已经激活
        //2.1 方案1：一个状态来个字段,子段很多，新加字段也要改代码
        // private int isRegister
        // private int isPhoneRealValid
        // privateint isEmailRealValid
        //.....
        //2.2 方案2（采纳）：用二进制位来表示，一位二进制就表示一个状态，使用多个二进制位就可以表示多个状态了。
        long status = BitStatesUtils.OP_REGISTED;
        status = BitStatesUtils.addState(status, BitStatesUtils.OP_ACTIVED);
        status = BitStatesUtils.addState(status, BitStatesUtils.OP_AUTHED_PHONE);
        vipBase.setBitState(status);
        vipBase.setLoginId(loginId);
        vipBaseMapper.insert(vipBase);

        VipUser vipUser = new VipUser();
        vipUser.setVipId(vipBase.getId());
        vipUserMapper.insert(vipUser);

        return AjaxResult.me();
    }
}